class O {
  void run() {
    print("this is O");
  }
}

/**
 * 成为mixin类的条件：
 *  1. 不能继承除了Object之外的任何类
 *  2. 不能有有参构造函数
 * 
 * 抽象类和普通类都可以是mixin类
 * 这个版本的dart，必须在mixin类前加mixin关键字声明
 */
mixin class A {
  String name = "A";

  A();

  // 下面这行无法通过编译，因为mixin类不能有有参构造函数
  // A.wrong(this.name);

  void printA() {
    print("A");
  }

  void run() {
    print("this is A");
  }
}

mixin class B {
  void printB() {
    print("B");
  }

  void run() {
    print("this is B");
  }
}

/**
 * 通过with继承了两个类，这两个类必须是mixin类
 * with必须在extends之后
 * 后面的类会覆盖前一个类中的同名方法
 */
class C extends O with A, B {}

void main() {
  C c = new C();
  c.printA();
  c.printB();

  // 执行A和B中相同的方法时，按照继承的顺序决定执行哪个类的方法，在后的优先（此处是B类优先）
  c.run();

  // 以下全都是true
  print("c is A: ");
  print(c is A);
  print("c is B: ");
  print(c is B);
  print("c is C: ");
  print(c is C);
  print("c is O: ");
  print(c is O);
}
